﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Controls;
using System.Windows;
using System.Security.Cryptography;
using System.Collections;
using System.Management;
using OFFICECORE = Microsoft.Office.Core;
using POWERPOINT = Microsoft.Office.Interop.PowerPoint;

namespace KinectControl
{
    public static class Uteis
    {
        private static string _publicKey = "!VI.2012.C#.WPF.NET4!";

        public static string PublicKey1
        {
            get { return _publicKey; }
        }

        public static IEnumerable<TSource> DistinctBy<TSource, TKey>
        (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            HashSet<TKey> knownKeys = new HashSet<TKey>();
            foreach (TSource element in source)
            {
                if (knownKeys.Add(keySelector(element)))
                {
                    yield return element;
                }
            }
        }

        public static void ExportToPng(Uri path, Canvas surface)
        {
            if (path == null) return;

            // Save current canvas transform
            Transform transform = surface.LayoutTransform;
            // reset current transform (in case it is scaled or rotated)
            surface.LayoutTransform = null;

            // Get the size of canvas
            Size size = new Size(surface.Width, surface.Height);
            // Measure and arrange the surface
            // VERY IMPORTANT
            surface.Measure(size);
            surface.Arrange(new Rect(size));

            // Create a render bitmap and push the surface to it
            RenderTargetBitmap renderBitmap =
              new RenderTargetBitmap(
                (int)size.Width,
                (int)size.Height,
                96d,
                96d,
                PixelFormats.Pbgra32);
            renderBitmap.Render(surface);

            try
            {
                // Create a file stream for saving image
                using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
                {
                    // Use png encoder for our data
                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                    // push the rendered bitmap to it
                    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                    // save the data to the stream
                    encoder.Save(outStream);

                    outStream.Flush();
                }

                // Restore previously saved layout
                surface.LayoutTransform = transform;

                GC.Collect();
            }
            catch (IOException ex)
            {
                Log.GravarLog(DateTime.Now + " - Capa nao gerada.", ex);
            }
        }

        public static BitmapImage CreateThumbNail(string caminhoImagem, int Altura, int Largura)
        {
            //gera um bitmap auxiliar para recuperar o altura/largura original da imagem
            BitmapImage bmpAux = new BitmapImage();
            bmpAux.BeginInit();
            bmpAux.UriSource = new Uri(caminhoImagem, UriKind.RelativeOrAbsolute);
            bmpAux.EndInit();

            // Create a BitmapImage and sets its DecodePixelWidth and DecodePixelHeight
            BitmapImage bmpImage = new BitmapImage();
            bmpImage.BeginInit();
            bmpImage.UriSource = new Uri(caminhoImagem, UriKind.RelativeOrAbsolute);


            if (bmpAux.Height > bmpAux.Width)
            {
                bmpImage.DecodePixelHeight = Altura; //seta uma altura padrao 170px
                bmpImage.DecodePixelWidth = Convert.ToInt32(Math.Round((Altura * bmpAux.Width) / bmpAux.Height)); //redimensiona a largura proporcionalmente a altura para um tamanho menor
            }
            else
            {
                bmpImage.DecodePixelWidth = Largura; //seta uma largura padrao 170px
                bmpImage.DecodePixelHeight = Convert.ToInt32(Math.Round((Largura * bmpAux.Height) / bmpAux.Width)); //redimensiona a largura proporcionalmente a altura para um tamanho menor
            }

            bmpImage.EndInit();

            return bmpImage;
        }
        
        public static FileInfo[] ListaFotosDoAlbum(string path, string Album)
        {
            DirectoryInfo imageDir;
            if (!string.IsNullOrEmpty(Album))
                imageDir = new DirectoryInfo(string.Format(path + @"\{0}\", Album));
            else
                imageDir = new DirectoryInfo(path);            

            string[] extensions = new[] { ".jpg", ".jpeg", ".png", ".tiff", ".bmp" };

            FileInfo[] AllImages =
                imageDir.EnumerateFiles()
                     .Where(f => extensions.Contains(f.Extension.ToLower()) && !f.FullName.Contains("capa")).OrderBy(t => t.CreationTime.Ticks)
                     .ToArray();
            return AllImages;
        }

        public static FileInfo[] ListaPowerPointFile()
        {
            DirectoryInfo imageDir = new DirectoryInfo(Config.PastaRaiz);

            string[] extensions = new[] { ".ppt", ".pptx", ".pps", ".ppsx" };

            FileInfo[] AllPPT =
                imageDir.EnumerateFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray();
            return AllPPT;
        }

        public static void exportaPPTtoPNG(string file, string pathAlbum, string pathProcessado)
        {
            POWERPOINT.Application App = new Microsoft.Office.Interop.PowerPoint.Application();

            POWERPOINT.Presentation pres =
                App.Presentations.Open(file, OFFICECORE.MsoTriState.msoTrue, OFFICECORE.MsoTriState.msoFalse, OFFICECORE.MsoTriState.msoFalse);

            pres.SaveCopyAs(pathAlbum, POWERPOINT.PpSaveAsFileType.ppSaveAsPNG, OFFICECORE.MsoTriState.msoFalse);
            pres.Close();

            MoveArquivo(file, pathProcessado);
        }

        private static void MoveArquivo(string OriginalPathFile, string DestPathFile)
        {
            if (File.Exists(DestPathFile))
                File.Delete(DestPathFile);

            File.Move(OriginalPathFile, DestPathFile);
        }

        //Calcula Hash md5 a partir de um array de byte
        public static string CalculateMD5Hash(byte[] imgAsBytes)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            try
            {
                byte[] result = md5.ComputeHash(imgAsBytes);

                // Build the final string by converting each byte
                // into hex and appending it to a StringBuilder
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < result.Length; i++)
                {
                    sb.Append(result[i].ToString("X2"));
                }

                // And return it
                return sb.ToString();
            }
            catch (ArgumentNullException)
            {
                Console.WriteLine("Hash has not been generated.");
                return null;
            }
        }

        //Calcula Hash md5 a partir de uma string
        public static string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));

            }
            return sb.ToString();
        }


        public static string getProcessorID()
        {
            ManagementObjectCollection mbsList = null;
            ManagementObjectSearcher mbs = new ManagementObjectSearcher("Select * From Win32_processor");
            mbsList = mbs.Get();
            string id = "";
            foreach (ManagementObject mo in mbsList)
            {
                id = mo["ProcessorID"].ToString();
            }

            return id;
        }

    }
}
